package com.xinqi.modules.sys.stats.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xinqi.common.base.constants.C;
import com.xinqi.common.base.utils.date.Dates;
import com.xinqi.common.redis.utils.Caches;
import com.xinqi.modules.sys.stats.convert.HomePageDayStConvert;
import com.xinqi.modules.sys.stats.domain.HomePageDayStEntity;
import com.xinqi.modules.sys.stats.dto.req.HomePageDayStQueryDTO;
import com.xinqi.modules.sys.stats.dto.rsp.HomePageDayStResultDTO;
import com.xinqi.modules.sys.stats.manager.HomePageDayStManager;
import com.xinqi.modules.sys.stats.service.HomePageDayStService;
import lombok.RequiredArgsConstructor;
import org.redisson.api.RSet;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 首页每天数据统计服务层实现
 *
 * @author: linkai
 * @date: 2023/04/25
 */
@Validated
@Service("homePageDayStService")
@RequiredArgsConstructor
public class HomePageDayStServiceImpl implements HomePageDayStService {
    private final HomePageDayStConvert homePageDayStConvert;
    private final HomePageDayStManager homePageDayStManager;
    private final RedissonClient redissonClient;

    /**
     * 查询 首页每天数据统计数据
     */
    @Override
    @DS("slaver")
    public List<HomePageDayStResultDTO> list(HomePageDayStQueryDTO query) {
        LambdaQueryWrapper<HomePageDayStEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.ge(Objects.nonNull(query.getStatDate()), HomePageDayStEntity::getStatsDate, query.getStatDate())
            .le(Objects.nonNull(query.getEndDate()), HomePageDayStEntity::getStatsDate, query.getEndDate())
            .orderByAsc(HomePageDayStEntity::getStatsDate);
        return homePageDayStManager.list(wrapper).stream()
            .map(homePageDayStConvert::convert).collect(Collectors.toList());
    }


    @Override
    public HomePageDayStResultDTO today(LocalDate statDate, LocalDate endDate) {
        LocalDateTime startTime = statDate.atTime(LocalTime.MIN);
        LocalDateTime endTime = endDate.plusDays(1).atTime(LocalTime.MIN);
        HomePageDayStResultDTO result = homePageDayStConvert.convert(homePageDayStManager.findByStatsDate(LocalDate.now()));
        // 课程-考勤
        Integer courseAttendance = homePageDayStManager.findCourseAttendance(startTime, endTime);
        result.setCourseAttendance(courseAttendance);
        // 课程-公告
        Integer courseNotice = homePageDayStManager.findCourseNotice(startTime, endTime);
        result.setCourseNotice(courseNotice);
        // 课程-讨论
        Integer courseDiscuss = homePageDayStManager.findCourseDiscuss(startTime, endTime);
        result.setCourseDiscuss(courseDiscuss);
        // 课程-测评
        Integer courseExam = homePageDayStManager.findCourseExam(startTime, endTime);
        result.setCourseExam(courseExam);
        // 课程-作业
        Integer courseTask = homePageDayStManager.findCourseHomework(startTime, endTime);
        result.setCourseTask(courseTask);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateToday() {
        LocalDate date = LocalDate.now();
        LocalDateTime startTime = LocalDateTime.of(date, LocalTime.MIN);
        LocalDateTime endTime = LocalDateTime.of(date.plusDays(1), LocalTime.MIN);
        HomePageDayStEntity entity = Optional.ofNullable(homePageDayStManager.findByStatsDate(date))
            .orElseGet(() -> {
                HomePageDayStEntity temp = new HomePageDayStEntity();
                temp.setStatsDate(date);
                return temp;
            });
        // 新增用户数量
        Integer addedUserNum = homePageDayStManager.findAddedUserNum(startTime, endTime);
        entity.setAddedUserNum(addedUserNum);
        // 注销用户总数量
        Integer loggedUserTotal = homePageDayStManager.findLoggedUserTotal();
        entity.setLoggedUserTotal(loggedUserTotal);
        // 用户总数量
        Integer userTotal = homePageDayStManager.findUserTotal();
        entity.setUserTotal(userTotal);
        // 新增课程数
        Integer addedCourseNum = homePageDayStManager.findAddedCourseNum(startTime, endTime);
        entity.setAddedCourseNum(addedCourseNum);
        // 课程总数
        Integer courseTotal = homePageDayStManager.findCourseTotal();
        entity.setCourseTotal(courseTotal);
        // 新班级程数
        Integer addedClassNum = homePageDayStManager.findAddedClassNum(startTime, endTime);
        entity.setAddedClassNum(addedClassNum);
        // 课程总数
        Integer classTotal = homePageDayStManager.findClassTotal();
        entity.setClassTotal(classTotal);
        // 用户活跃度
        String key = Caches.formatKey(C.CacheKey.USER_ACTIVITY_SET, Dates.format(date, "yyyyMMdd"));
        RSet<Long> userActivitySet = redissonClient.getSet(key);
        entity.setUserActivityNum(userActivitySet.isExists() ? userActivitySet.size() : 0);
        // 课程-考勤
        Integer courseAttendance = homePageDayStManager.findCourseAttendance(startTime, endTime);
        entity.setCourseAttendance(courseAttendance);
        // 课程-公告
        Integer courseNotice = homePageDayStManager.findCourseNotice(null, null);
        entity.setCourseNotice(courseNotice);
        // 课程-讨论
        Integer courseDiscuss = homePageDayStManager.findCourseDiscuss(null, null);
        entity.setCourseDiscuss(courseDiscuss);
        // 课程-测评
        Integer courseExam = homePageDayStManager.findCourseExam(null, null);
        entity.setCourseExam(courseExam);
        // 课程-作业
        Integer courseTask = homePageDayStManager.findCourseHomework(null, null);
        entity.setCourseTask(courseTask);
        return homePageDayStManager.saveOrUpdate(entity);
    }

}
